1 // Fig. 21.7: fig21_07.cpp 2 // Demonstrating dynamic_cast. 3 #include 4 5 const double PI = 3.14159; 6 7 class Shape { 8 public: 9 virtual double area() const { return 0.0; } 10 }; 11 12 class Circle: public Shape { 13 public: 14 Circle( int r = 1 ) { radius = r; } 15 16 virtual double area() const 17 { 18 return PI * radius * radius; 19 }; 20 protected: 21 int radius; 22 }; 23 24 class Cylinder: public Circle { 25 public: 26 Cylinder( int h = 1 ) { height = h; } 27 28 virtual double area() const 29 { 30 return 2 * PI * radius * height + 31 2 * Circle::area(); 32 } 33 private: 34 int height; 35 }; 36 37 void outputShapeArea( const Shape * ); // prototype 38 39 int main() 40 { 41 Circle circle; 42 Cylinder cylinder; 43 Shape *ptr = 0; 44 45 outputShapeArea( &circle ); // output circle's area 46 outputShapeArea( &cylinder ); // output cylinder's area 47 outputShapeArea( ptr ); // attempt to output area 48 return 0; 49 } 50 51 void outputShapeArea( const Shape *shapePtr ) 52 { 53 const Circle *circlePtr; 54 const Cylinder *cylinderPtr; 55 56 // cast Shape * to a Cylinder * 57 cylinderPtr = dynamic_cast< const Cylinder * >( shapePtr ); 58 59 if ( cylinderPtr != 0 ) // if true, invoke area() 60 cout << "Cylinder's area: " << cylinderPtr->area(); 61 else { // shapePtr does not refer to a cylinder 62 63 // cast shapePtr to a Circle * 64 circlePtr = dynamic_cast< const Circle * >( shapePtr ); 65 66 if ( circlePtr != 0 ) // if true, invoke area() 67 cout << "Circle's area: " << circlePtr->area(); 68 else 69 cout << "Neither a Circle nor a Cylinder."; 70 } 71 72 cout << endl; 73 } }